#ifndef IMAGE
#define IMAGE
#include <iostream>
#include <FreeImage.h>

class Image
{
private:
    FIBITMAP* bitmap;
    double **red;
    double **green;
    double **blue;

    double **Y;
    double **Cb;
    double **Cr;
    
    int width, height, pitch;
public:

    Image(std::string file);
    
    Image(double **y, double** cb, double** cr, int w, int h):Y(y),Cb(cb),Cr(cr),width(w),height(h)
    {
      red = new double *[height];
      green = new double *[height];
      blue = new double *[height];

	for(int i=0; i< height; i++)
	{
	    red[i]=new double [width];
	    green[i]=new double [width];
	    blue[i]=new double [width];
	}
    }
    
    Image(char **y, char** cb, char** cr, int w, int h):width(w),height(h)
    {
      red = new double *[height];
      green = new double *[height];
      blue = new double *[height];

      Y = new double *[height];
      Cb = new double *[height];
      Cr = new double *[height];
      
	for(int i=0; i< height; i++)
	{
	    red[i]=new double [width];
	    green[i]=new double [width];
	    blue[i]=new double [width];
	    
	    Y[i] = new double [width];
	    Cb[i] = new double [width];
	    Cr[i] = new double [width];
	}
	
	
	for(int i=0; i<height; ++i)
	{
	    for(int j=0; j<width; ++j)
	    {
		Y[i][j]=(double)y[i][j];
		Cb[i][j]=(double)cb[i][j];
		Cr[i][j]=(double)cr[i][j];
	    }
	}
	
	
    }
    
    
    
    
    
    
    
    
    void saveImage(std::string file)
    {
	FIBITMAP *bitmapOut = FreeImage_Allocate(width, height, 24);
      
	RGBQUAD color;
	
	std::cout<<"start save file"<<std::endl;
	
	for(int y = 0; y < height; y++)
        {
            for(int x = 0; x < width; x++)
            {	
		 color.rgbRed=red[y][x];
		 color.rgbGreen=green[y][x];
		 color.rgbBlue=blue[y][x];
		 FreeImage_SetPixelColor(bitmapOut,x,y,&color);
	    }
	}
	
	
	if(FreeImage_Save(FIF_PNG, bitmapOut,file.c_str()))
	{
	    std::cout<<"DONE"<<std::endl;
	}
    }
    
    
    void separateColor();
    
    void rgbToYCbCr();

    void YCbCrToRgb(int width,  int height);
   
    ~Image()
    {
        FreeImage_Unload(bitmap);

        for(int i=0; i < height; ++i)
        {
            delete [] red[i];
            delete [] green[i];
            delete [] blue[i];
            delete [] Y[i];
            delete [] Cb[i];
            delete [] Cr[i];
        }

        delete [] Y;
        delete [] Cb;
        delete [] Cr;
        delete [] red;
        delete [] green;
        delete [] blue;
    }

  
    int getWidth()
    {
        return width;
    }

    int getHeight()
    {
        return height;
    }

    FIBITMAP* getBitMap()
    {
        return bitmap;
    }

    double** getRedTable()
    {
        return red;
    }

    double** getBlueTable()
    {
        return blue;
    }

    double** getGreenTable()
    {
        return green;
    }

    double** getYTable()
    {
        return Y;
    }

    double** getCbTable()
    {
        return Cb;
    }


    double** getCrTable()
    {
        return Cr;
    }
    
    static int cat(int a)
    {
        if(a<0)
        {
            return 0;
        }else if(a>255)
        {
            return 255;
        }else
            return a;
    }

};

#endif
